package space.sakana.edusysback.service;

import com.alibaba.fastjson2.JSON;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import space.sakana.edusysback.emu.QuestionEnum;
import space.sakana.edusysback.entity.Admin;
import space.sakana.edusysback.entity.Teacher;
import space.sakana.edusysback.entity.User;
import space.sakana.edusysback.entity.job.Job;
import space.sakana.edusysback.entity.job.JobPush;
import space.sakana.edusysback.entity.job.JobTarget;
import space.sakana.edusysback.entity.paper.FullPaper;
import space.sakana.edusysback.entity.paper.PaperItem;
import space.sakana.edusysback.entity.question.Question;
import space.sakana.edusysback.entity.question.type.EssayQuestion;
import space.sakana.edusysback.entity.question.type.MultipleChoice;
import space.sakana.edusysback.entity.question.type.SingleChoice;
import space.sakana.edusysback.entity.question.type.TrueFalseQ;
import space.sakana.edusysback.mapper.AdminMapper;
import space.sakana.edusysback.mapper.TeacherMapper;
import space.sakana.edusysback.mapper.UserMapper;
import space.sakana.edusysback.mapper.cls.ClsUserMapper;
import space.sakana.edusysback.mapper.job.JobMapper;
import space.sakana.edusysback.mapper.paper.PaperItemMapper;
import space.sakana.edusysback.mapper.question.QuestionMapper;
import space.sakana.edusysback.result.DataResult;
import space.sakana.edusysback.result.Result;
import space.sakana.edusysback.util.CookieUtil;
import space.sakana.edusysback.util.IpUtil;
import space.sakana.edusysback.util.TimeUtil;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserService {
    private UserMapper userMapper;
    private JobMapper jobMapper;
    private AdminMapper adminMapper;
    private TeacherMapper teacherMapper;
    private PaperItemMapper paperItemMapper;
    private QuestionMapper questionMapper;
    private ClsUserMapper clsUserMapper;

    @Autowired
    public void autowiredMapper(UserMapper userMapper, JobMapper jobMapper, AdminMapper adminMapper,
                                TeacherMapper teacherMapper, PaperItemMapper paperItemMapper, QuestionMapper questionMapper,
                                ClsUserMapper clsUserMapper) {
        this.userMapper = userMapper;
        this.jobMapper = jobMapper;
        this.adminMapper = adminMapper;
        this.teacherMapper = teacherMapper;
        this.paperItemMapper = paperItemMapper;
        this.questionMapper = questionMapper;
        this.clsUserMapper = clsUserMapper;
    }

    public Result getUser(int uid, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        return new DataResult(JSON.toJSONString(userMapper.selectUserById(uid)));
    }

    public Result getAllUser(HttpServletRequest request, HttpServletResponse response){
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        return new DataResult(JSON.toJSONString(userMapper.selectAllUsers()));
    }

    public Result updateUser(String data, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        return new Result(userMapper.updateUser(JSON.parseObject(data, User.class)));
    }

    public Result addUsers(String data, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        return new Result(userMapper.insertUser(JSON.parseObject(data, User.class)));
    }

    public Result getJobTargetUser(int jid, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }

        List<JobTarget> jobTargets = jobMapper.selectAllJobTarget(jid);
        List<User> users = new ArrayList<>();
        for (JobTarget jobTarget :jobTargets) {
            User user = userMapper.selectUserById(jobTarget.getUid());
            users.add(user);
        }
        return new DataResult(JSON.toJSONString(users));
    }

    public User getLoginUser(HttpServletRequest request){
        return userMapper.selectUserByToken(CookieUtil.getCookieValueByKey("token", request));
    }

    public Result getUserTask(HttpServletRequest request, HttpServletResponse response) {
        User user = userMapper.selectUserByToken(CookieUtil.getCookieValueByKey("token", request));
        if (user==null){
            return Result.failResult;
        }

        List<JobTarget> jobTargets = jobMapper.selectJobByUid(user.getId());
        List<Job> jobs = new ArrayList<>();
        for (JobTarget jobtarget :jobTargets) {
            int jid = jobtarget.getJid();
            Job job = jobMapper.selectJobById(jid);
            if (job!=null){
                if (jobtarget.getPush()==1){
                    job.setFinish(1);
                }
                Teacher teacher = teacherMapper.selectTeacherById(job.getTid());
                if (teacher!=null){
                    job.setCreator(teacher.getName());
                }
                jobs.add(job);
            }
        }
        return new DataResult(JSON.toJSONString(jobs));
    }

    public Result checkUser(HttpServletRequest request, HttpServletResponse response) {
        User user = userMapper.selectUserByToken(CookieUtil.getCookieValueByKey("token", request));
        if (user==null){
            return Result.failResult;
        }
        user.setIp(IpUtil.getIpAddr(request));
        user.setLrt(TimeUtil.getTimeStamp());
        userMapper.updateUser(user);
        return Result.successResult;
    }

    public Result checkAdmin(HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }
        return Result.successResult;
    }

    @Nullable
    public Result getPaper(int id, HttpServletRequest request, HttpServletResponse response) {
        User user = userMapper.selectUserByToken(CookieUtil.getCookieValueByKey("token", request));
        if (user==null){
            return Result.failResult;
        }

        Job job = jobMapper.selectJobById(id);
        int pid = job.getPid();
        List<PaperItem> paperItems = paperItemMapper.selectPaperItemByPid(pid);
        FullPaper fullPaper = new FullPaper();
        fullPaper.setPid(pid);
        for (PaperItem paperItem :paperItems) {
            Question question = questionMapper.selectQuestionById(paperItem.getQid());
            if (question.getType()==QuestionEnum.SINGLE_CHOICE.getQuestionInt()){
                SingleChoice singleChoice = questionMapper.selectQuestionAById(question.getId());
                if (singleChoice==null){
                    continue;
                }
                singleChoice.setAnswer("");
                singleChoice.setScore(paperItem.getScore());
                fullPaper.addSingleChoice(singleChoice);
            }
            else if (question.getType()==QuestionEnum.MULTIPLE_CHOICE.getQuestionInt()){
                MultipleChoice multipleChoice = questionMapper.selectQuestionBById(question.getId());
                if (multipleChoice==null){
                    continue;
                }
                multipleChoice.setAnswer("");
                multipleChoice.setScore(paperItem.getScore());
                fullPaper.addMultipleChoice(multipleChoice);
            }
            else if (question.getType()==QuestionEnum.TRUE_FALSE_Q.getQuestionInt()){
                TrueFalseQ trueFalseQ = questionMapper.selectQuestionCById(question.getId());
                if (trueFalseQ==null){
                    continue;
                }
                trueFalseQ.setAnswer("");
                trueFalseQ.setScore(paperItem.getScore());
                fullPaper.addTrueFalseQ(trueFalseQ);
            }
            else if (question.getType()==QuestionEnum.ESSAY_QUESTION.getQuestionInt()){
                EssayQuestion essayQuestion = questionMapper.selectQuestionDById(question.getId());
                if (essayQuestion==null){
                    continue;
                }
                essayQuestion.setAnswer("");
                essayQuestion.setScore(paperItem.getScore());
                fullPaper.addEssayQuestion(essayQuestion);
            }
        }
        return new DataResult(JSON.toJSONString(fullPaper));
    }

    public Result deleteUser(int uid, HttpServletRequest request, HttpServletResponse response) {
        Admin admin = adminMapper.selectAdminByToken(CookieUtil.getCookieValueByKey("token", request));
        if (admin==null){
            return Result.failResult;
        }
        clsUserMapper.deleteClsUser(uid);
        jobMapper.deleteJobPushByUid(uid);
        jobMapper.deleteJobPushItemByUid(uid);
        jobMapper.deleteJobTargetByUid(uid);
        userMapper.deleteUser(uid);
        return new Result(1);
    }
}
